#include <iostream>
#include "ExportFile.h"

using namespace std;

int s_animMax = 0;

vector < Sprite_Export > getSpriteList ( char* spriteListFile )
{
	char spriteID[50], spriteName[50], spritePath[256], temp[10];
	char *line;
	int plistType = 0;

	FILE* f = fopen ( spriteListFile, "r" );	
	vector < Sprite_Export > _spriteList;
	
	if ( f == NULL )
	{
		cout << "Can not read file: " << spriteListFile << endl;
		return _spriteList;
	}
	while ( !feof ( f ) )
	{
		fscanf ( f, "%s" "%s" "%s", &spriteID, &temp, &spritePath );

		if ( spriteID[0] == '\0' )
			continue;
		//spriteID
		for (int i = 0; i < strlen( spriteID ) - 2; i ++ )
			spriteID[i] = spriteID[i + 1];
		spriteID[ strlen( spriteID ) - 2 ] = '\0';

		//sprite name
		char temp[50]; 
			for (int i = strlen ( spritePath ) - 2; i >= 0; i-- )
			{	
				if ( spritePath[i] == '\\' )
				{
					temp[strlen ( spritePath ) - 2 - i] = '\0';
					break;
				}
				temp[strlen ( spritePath ) - 2 - i] = spritePath[i];
			}

			for (int i = strlen ( temp ) - 1; i >= 0; i-- )
			{	
				
				spriteName[strlen ( temp ) - 1 - i] = temp[i];
			}
			spriteName[strlen ( temp ) ] = '\0';		

			//push
			Sprite_Export sprite_ex;
			strcpy ( sprite_ex.spriteID, strupr(spriteID) );
			strcpy ( sprite_ex.spriteName, spriteName );
			sprite_ex.plistType = 0;
			if ( Util::getInstant()->isExist ( sprite_ex.spriteName ) && Util::getInstant()->isExist ( Util::getInstant()->getImageNameWithExtent ( sprite_ex.spriteName ) ) )
				_spriteList.push_back ( sprite_ex );
			else
			{
				cout << endl << "Build sprite: " << sprite_ex.spriteName << "       -----ERROR------" << endl;
				if ( !Util::getInstant()->isExist ( sprite_ex.spriteName ) )
					cout << "Not exist sprite: " << sprite_ex.spriteName;
				else if ( !Util::getInstant()->isExist ( Util::getInstant()->getImageNameWithExtent ( sprite_ex.spriteName ) )) 
					cout << "Not exist image: " << Util::getInstant()->getImageNameWithExtent ( sprite_ex.spriteName );
			}

			memset ( spriteID, 0, sizeof (spriteID) );
			memset ( spriteName, 0, sizeof (spriteName) );
			memset ( spritePath, 0, sizeof (spritePath) );
	}
	fclose ( f );
	return _spriteList;
}

ExportFile* ExportFile::instant;

ExportFile* ExportFile::getInstant()
{
	if ( instant == NULL )
		instant = new ExportFile();
	return instant;
}

int ExportFile::spriteListSuccess ( char* spriteListFile )
{
	char spriteID[50], spriteName[50], spritePath[256], temp[10];
	char *line;
	int plistType = 0, success = 1;

	FILE* f = fopen ( spriteListFile, "r" );	
	vector < Sprite_Export > _spriteList;
	
	if ( f == NULL )
	{
		cout << "Can not read file: " << spriteListFile << endl;
		return 0;
	}
	while ( !feof ( f ) )
	{
		fscanf ( f, "%s" "%s" "%s", &spriteID, &temp, &spritePath );

		if ( spriteID[0] == '\0' )
			continue;
		//spriteID
		for (int i = 0; i < strlen( spriteID ) - 2; i ++ )
			spriteID[i] = spriteID[i + 1];
		spriteID[ strlen( spriteID ) - 2 ] = '\0';

		//sprite name
		char temp[50]; 
			for (int i = strlen ( spritePath ) - 2; i >= 0; i-- )
			{	
				if ( spritePath[i] == '\\' )
				{
					temp[strlen ( spritePath ) - 2 - i] = '\0';
					break;
				}
				temp[strlen ( spritePath ) - 2 - i] = spritePath[i];
			}

			for (int i = strlen ( temp ) - 1; i >= 0; i-- )
			{	
				
				spriteName[strlen ( temp ) - 1 - i] = temp[i];
			}
			spriteName[strlen ( temp ) ] = '\0';		

			//push
			Sprite_Export sprite_ex;
			strcpy ( sprite_ex.spriteID, strupr(spriteID) );
			strcpy ( sprite_ex.spriteName, spriteName );
			sprite_ex.plistType = 0;
			if ( Util::getInstant()->isExist ( sprite_ex.spriteName ) && Util::getInstant()->isExist ( Util::getInstant()->getImageNameWithExtent ( sprite_ex.spriteName ) ) )
				_spriteList.push_back ( sprite_ex );
			else
			{
				cout << endl << "Build sprite: " << sprite_ex.spriteName << "       -----ERROR------" << endl;
				if ( !Util::getInstant()->isExist ( sprite_ex.spriteName ) )
					cout << "Not exist sprite: " << sprite_ex.spriteName;
				else if ( !Util::getInstant()->isExist ( Util::getInstant()->getImageNameWithExtent ( sprite_ex.spriteName ) )) 
					cout << "Not exist image: " << Util::getInstant()->getImageNameWithExtent ( sprite_ex.spriteName );
				success  = 0;
			}

			memset ( spriteID, 0, sizeof (spriteID) );
			memset ( spriteName, 0, sizeof (spriteName) );
			memset ( spritePath, 0, sizeof (spritePath) );
	}

	return success;
}

void ExportFile::exportPlistFile ( char* spriteListFile )
{
	
}

void ExportFile::beginSpriteDefine ( char* spriteListFile )
{
	FILE* fout = fopen ( "SpriteDefine.h", "w");
	fprintf ( fout, "#ifndef _SPRITE_DEFINE_H");
	fprintf ( fout, "\n#define _SPRITE_DEFINE_h");
	fclose ( fout );
}

void ExportFile::endSpriteDefine ( char* spriteListFile )
{
	FILE* fout = fopen ( "SpriteDefine.h", "a");
	fprintf ( fout, "\n#endif" );
	fclose ( fout );
}

void ExportFile::spriteIDSpriteDefine ( char* spriteListFile )
{
	FILE* fout = fopen ( "SpriteDefine.h", "a");

	vector < Sprite_Export > spriteList = getSpriteList ( spriteListFile );
	ExportPlist* _export = NULL;
	fprintf ( fout, "\n\n//sprite ID" );
	int count = 0;
	for ( vector < Sprite_Export >::iterator i = spriteList.begin(); i != spriteList.end(); i++ )
	{
		fprintf ( fout, "\n#define SPRITE_%s %d", strupr( (*i).spriteID ) , count );		
		count++;
	}
	fprintf ( fout, "\n#define SPRITE_MAX %d", count );	
	fclose ( fout );
}

void ExportFile::frameIDSpriteDefine ( char* spriteListFile )
{
	int frameMax = 0;
	int animMax = 0;
	int charLenghMax = 0;
	FILE* fout = fopen ( "SpriteDefine.h", "a");

	vector < Sprite_Export > spriteList = getSpriteList ( spriteListFile );
	ExportPlist* _export = NULL;
	fprintf ( fout, "\n\n//frame ID" );
	
	for ( vector < Sprite_Export >::iterator i = spriteList.begin(); i != spriteList.end(); i++ )
	{
		int count = 0;
		fprintf ( fout, "\n//frame ID of %s", strupr( (*i).spriteID ) );
		
		SpriteAurora* sprite = Performance::getInstant()->LoadSprite ( (*i).spriteName );
		//frame with module
		for ( int j = 0; j < sprite->numOfModule; j++ )
			if ( !(sprite->module[j].moduleSize.x == -1 && sprite->module[j].moduleSize.y == -1 && sprite->module[j].moduleSize.w == -1 && sprite->module[j].moduleSize.h == -1 ) )
			{
				fprintf ( fout, "\n#define %s %d", strupr ( sprite->module[j].moduleName ), count++ );
				if ( charLenghMax < strlen ( sprite->module[j].moduleName ) )
					charLenghMax = strlen ( sprite->module[j].moduleName );
			}
		

		//frame with anim
		for ( int j = 0; j < sprite->numOfAnim; j++ )
		{
			fprintf ( fout, "\n#define %s %d", strupr ( sprite->anim[j].animName ), j );
			for ( int k = 0; k < sprite->anim[j].numAframe; k++ )
			{
				count++;
				if ( charLenghMax < strlen ( sprite->anim[j].animName ) )
					charLenghMax = strlen ( sprite->anim[j].animName );				
			}			
		}	
		if ( frameMax < ( count - 1) )
			frameMax = count;
		if ( animMax < sprite->numOfAnim )
			animMax = sprite->numOfAnim;

	}	
	s_animMax = animMax;
	fprintf ( fout, "\n#define FRAME_MAX %d", frameMax );
	fprintf ( fout, "\n#define ANIM_MAX %d", animMax );
	fprintf ( fout, "\n#define FRAME_STRING_LENGTH %d", charLenghMax + 10 ); // include .png\0
	fclose ( fout );
}

void ExportFile::stringFrameSpriteDefine ( char* spriteListFile )
{
	FILE* fout = fopen ( "SpriteDefine.h", "a");

	fprintf ( fout, "\n//string of frame" );
	fprintf ( fout, "\nstatic char s_spriteFrame[SPRITE_MAX][FRAME_MAX][FRAME_STRING_LENGTH] = \n{");

	vector < Sprite_Export > spriteList = getSpriteList ( spriteListFile );
	ExportPlist* _export = NULL;	
	int count = 0;
	for ( vector < Sprite_Export >::iterator i = spriteList.begin(); i != spriteList.end(); i++ )
	{
		fprintf ( fout, "\n\t{" );
		SpriteAurora* sprite = Performance::getInstant()->LoadSprite ( (*i).spriteName );
		//frame with module
		for ( int j = 0; j < sprite->numOfModule; j++ )
			if ( !(sprite->module[j].moduleSize.x == -1 && sprite->module[j].moduleSize.y == -1 && sprite->module[j].moduleSize.w == -1 && sprite->module[j].moduleSize.h == -1 ) )
				fprintf ( fout, "\n\t\t\"%s.png\",", sprite->module[j].moduleName );
		
		//frame with anim
		for ( int j = 0; j < sprite->numOfAnim; j++ )
		{
			int k;
			for ( k = 0; k < sprite->anim[j].numAframe; k++ )
				fprintf ( fout, "\n\t\t\"%s_%d.png\",", sprite->anim[j].animName, k );		
		}
		
		fprintf ( fout, "\n\t}," );		
	}
	

	fprintf ( fout, "\n};");	
	fclose ( fout );
}

void ExportFile::stringAnimSpriteDefine ( char* spriteListFile )
{
	FILE* fout = fopen ( "SpriteDefine.h", "a");

	fprintf ( fout, "\n//anim array" );
	fprintf ( fout, "\n#define FRAME_BEGIN 0" );
	fprintf ( fout, "\n#define FRAME_END 1" );

	if ( s_animMax != 0 )
	{
		fprintf ( fout, "\nstatic char s_spriteAnim[SPRITE_MAX][ANIM_MAX][2] = \n{");

		vector < Sprite_Export > spriteList = getSpriteList ( spriteListFile );
		ExportPlist* _export = NULL;	
		int count = 0;
		for ( vector < Sprite_Export >::iterator i = spriteList.begin(); i != spriteList.end(); i++ )
		{
			count = 0;
		
			SpriteAurora* sprite = Performance::getInstant()->LoadSprite ( (*i).spriteName );
			//frame with module
			for ( int j = 0; j < sprite->numOfModule; j++ )
				if ( !(sprite->module[j].moduleSize.x == -1 && sprite->module[j].moduleSize.y == -1 && sprite->module[j].moduleSize.w == -1 && sprite->module[j].moduleSize.h == -1 ) )
					count++;
		
			//frame with anim
			fprintf ( fout, "\n\t{" );
			for ( int j = 0; j < sprite->numOfAnim; j++ )
			{			
				for ( int k = 0; k < sprite->anim[j].numAframe; k++ )
				{				
					if ( k == 0 ) 
						fprintf ( fout, "\n\t\t{ %d, ", count );	
					if ( k == sprite->anim[j].numAframe - 1 )
						fprintf ( fout, "%d },", count );	
					count++;
				}
			
			}
		
			fprintf ( fout, "\n\t}," );		
		}
	

		fprintf ( fout, "\n};");	
	}
	else
		fprintf ( fout, "\nstatic char s_spriteAnim[SPRITE_MAX][1][2];");
	fclose ( fout );
}

void ExportFile::spriteListSpriteDefine ( char* spriteListFile )
{
	FILE* fout = fopen ( "SpriteDefine.h", "a");
	vector < Sprite_Export > spriteList = getSpriteList ( spriteListFile );
	int imageLength = 0;
	for ( vector < Sprite_Export >::iterator i = spriteList.begin(); i != spriteList.end(); i++ )
	{
		if ( imageLength < strlen ( Util::getInstant()->getImageNameWithExtent( (*i).spriteName ) ) )
			imageLength = strlen ( Util::getInstant()->getImageNameWithExtent( (*i).spriteName ) );
	}

	fprintf ( fout, "\n//sprite list" );
	fprintf ( fout, "\nstatic char s_spriteList[SPRITE_MAX][%d] = \n{", imageLength + 1);

	
	ExportPlist* _export = NULL;	
	for ( vector < Sprite_Export >::iterator i = spriteList.begin(); i != spriteList.end(); i++ )
	{
		fprintf ( fout, "\n\t\"%s\",", Util::getInstant()->getImageNameWithExtent( (*i).spriteName ) );		
	}
	

	fprintf ( fout, "\n};");	
	fclose ( fout );
}

void ExportFile::plistListSpriteDefine ( char* spriteListFile )
{
	FILE* fout = fopen ( "SpriteDefine.h", "a");
	vector < Sprite_Export > spriteList = getSpriteList ( spriteListFile );
	int imageLength = 0;
	for ( vector < Sprite_Export >::iterator i = spriteList.begin(); i != spriteList.end(); i++ )
	{
		if ( imageLength < strlen ( Util::getInstant()->getImageName( (*i).spriteName ) ) )
			imageLength = strlen ( Util::getInstant()->getImageName( (*i).spriteName ) );
	}

	fprintf ( fout, "\n//plist list" );
	fprintf ( fout, "\nstatic char s_plistList[SPRITE_MAX][%d] = \n{", imageLength + strlen (".plist") + 1 );

	
	for ( vector < Sprite_Export >::iterator i = spriteList.begin(); i != spriteList.end(); i++ )
	{
		fprintf ( fout, "\n\t\"%s.plist\",", Util::getInstant()->getImageName( (*i).spriteName ) );		
	}
	

	fprintf ( fout, "\n};");	
	fclose ( fout );

	ExportPlist* _export = NULL;
	for ( vector < Sprite_Export >::iterator i = spriteList.begin(); i != spriteList.end(); i++ )
	{
		_export = new ExportPlist ( );
		_export->setSpriteName( (*i).spriteName );
		_export->setPlistType ( (*i).plistType );
		_export->exportPlist();				
	}
}

void ExportFile::exportSpriteDefine ( char* spriteListFile )
{
	beginSpriteDefine( spriteListFile );
	spriteIDSpriteDefine( spriteListFile );
	frameIDSpriteDefine( spriteListFile );
	stringFrameSpriteDefine( spriteListFile );
	stringAnimSpriteDefine( spriteListFile );
	spriteListSpriteDefine ( spriteListFile );
	plistListSpriteDefine ( spriteListFile );
	endSpriteDefine( spriteListFile );
}